package ru.rchervot.sanasar.client.view;

import java.util.HashSet;

import ru.rchervot.sanasar.client.event.EventPageChange;
import ru.rchervot.sanasar.client.event.EventSelectedNone;
import ru.rchervot.sanasar.client.event.EventSelectedSeveral;
import ru.rchervot.sanasar.client.event.EventUIResultsScrollChange;
import ru.rchervot.sanasar.client.event.HandlerPageChange;
import ru.rchervot.sanasar.client.model.ResultsPage;
import ru.rchervot.sanasar.client.model.SearchResultsItem;
import ru.rchervot.sanasar.client.rpc.RPCServiceAsync;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;


public abstract class AbstractResultsPresenter implements ResultsPresenter {
	protected final HandlerManager eventBus;
	protected final RPCServiceAsync service;
	protected final Display display;
	protected ResultsPage<SearchResultsItem> page;
	private EventPageChange<SearchResultsItem> clickEvent;
	
	AbstractResultsPresenter(Display display, HandlerManager eventBus,
			RPCServiceAsync service) {
		this.display = display;
		this.eventBus = eventBus;
		this.service = service;
		listenForPageChange();
//		listenForSettingsChange();
	}
	
	@Override
	public void bindDisplay() {
		display.setPresenter(this);
	}
	
	protected void listenForPageChange() {
		eventBus.addHandler(EventPageChange.getType(),
				new HandlerPageChange<SearchResultsItem>() {
			@Override
			public void onPageChange(
					EventPageChange<SearchResultsItem> event) {
				if (event.isStartPage()) {
					display.showStartPage();
				} else {
					if (event.getPage().isEmpty()) {
						display.showEmptyPage();
					} else {
						renderPage(event.getPage());
						
						if (event != clickEvent) { // to prevent scrolling on click events
							eventBus.fireEvent(EventUIResultsScrollChange.build(
									display.getRowOffsetHeight(page.getCurrentRow())));
						}
					}
				}
			}
		});
	}
	
	private int currentPageSize = 0;
	
	private void renderPage(ResultsPage<SearchResultsItem> page) {
		if (currentPageSize != page.getPageSize()) {
			currentPageSize = page.getPageSize();
			
			display.resizeTable(currentPageSize);
			
			listenForRowSelection();
		}
		
		if (this.page != page) {
			this.page = page;
			
			display.updateItems(page.getItems(), page.getPageCurrentOffset());
		} 
		
		display.selectSingleRow(page.getCurrentRow());			
	}
	
//	private void listenForSettingsChange() {
//		eventBus.addHandler(EventSettingsChange.getType(),
//				new HandlerSettingsChange() {
//			@Override
//			public void onSettingsChange(EventSettingsChange event) {
//				applyNewSettings(event.getSettings());
//			}
//		});
//	}
//	
//	private void applyNewSettings(UserSettings settings) {
//		display.resizeTable(settings.getPageSize()); //TODO 
//	}
	
	void listenForRowSelection() {
		ClickHandler clickHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				HashSet<Integer> selectedRows = display.getSelectedRows();
				
				if (selectedRows.size() == 0) {
					eventBus.fireEvent(EventSelectedNone.build("Query Description Here?", 
							page.getResultsSize()));
				} else if (selectedRows.size() == 1) {
					int row = selectedRows.iterator().next();
					page.setOffset(page.getPageCurrentOffset() + row);
					
					clickEvent = EventPageChange.build(page);
					
					eventBus.fireEvent(clickEvent);
				} else if (selectedRows.size() > 1) {
					eventBus.fireEvent(EventSelectedSeveral.build(selectedRows.size()));
				}
			}
		};
		
		display.getTable().addClickHandler(clickHandler);
		
		for (HasClickHandlers checkBox : display.getCheckBoxes()) {
			checkBox.addClickHandler(clickHandler);
		}
	}
	
}
